package com.sf.algo.solve.solver;

import java.util.concurrent.Future;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.optaplanner.core.api.solver.SolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import com.sf.algo.solve.domain.Solution;


@Component
public class Solver {
	private static final Logger logger = LoggerFactory.getLogger(Solver.class);
	private static final String SOLVER_CONFIG = "solution.xml";
	private org.optaplanner.core.api.solver.Solver<Solution> mySolver;
	private SolverFactory<Solution> solverFactory;

	@Resource(name = "solverThreadPool")
	private ThreadPoolTaskExecutor solverThreadPool;

	@PostConstruct
	public void init() {
		solverFactory = SolverFactory.createFromXmlResource(SOLVER_CONFIG);
		mySolver = solverFactory.buildSolver();
		logger.info("Solver is init");
	}

	public Solution solve(Solution problem) {
		if (mySolver.isSolving()) {
			logger.info("Solver is solving. Stop it.");
			mySolver.terminateEarly();
			logger.info("Solver has stop.");
		}
		return mySolver.solve(problem);
	}

	public Future<Solution> submit(Solution problem) {
		return solverThreadPool.submit(() -> solve(problem));
	}
	
	public Solution getBestSolution() {
		return mySolver.getBestSolution();
	}
	
}
